home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Language/OS - Multiplatform Resource Library
/
LANGUAGE OS.iso
/
t3_1
/
doc.lha
/
documentation
/
manual
/
semantics.mss
< prev
next >
Wrap
Text File
|
1987-06-30
|
11KB
|
228 lines
@part[SEMANTICS, Root "TMAN.MSS"] @Comment{-*-System:TMAN-*-}
@chap[Syntax and semantics]
@label[SemanticsChapter]
@Comment{ref: implementation chapter; syntax chapter}
This chapter gives an overview of @Tau[] as a programming language. It
is important not to confuse the language @i[per se] with a particular
body of software which implements it. It is natural that this confusion
arises, both because the language and its implementations have
developed in parallel, and because this confusion is traditional
among Lisp dialects (for example, Maclisp and Lisp Machine Lisp).
The @tau[] language logically comprises three distinct components:
@begin[itemize]
an @iix[external representation] for objects as character sequences,
a @iix[core language] @dash[] syntax and semantics for expressions, and
a @iix[standard environment] @dash[] the behavior of the objects
which are values of system variables.
@end[itemize]
@section[External representation]
Like other Lisp dialects, and in contrast with most other
programming languages, @Tau[] has two different kinds of syntax: the
@iix[external representation] by which objects (data) are represented as a
linear sequence of characters, and an @iix[expression syntax] by which
these objects can be understood as programs.@index[objects]
That is, the meaning of a @Tau[] program represented as characters in a file
or other external storage medium must be determined in two stages:
first, by mapping the characters to objects, and then by interpreting
these objects as executable programs.
The external syntax of @Tau[] is very similar to that of other Lisp
dialects, and is discussed in detail at appropriate places in this manual.
The following gives only the most cursory description.
@dc{ Uck!!! }
Characters may be classified according to their lexical properties; the
two most important distinctions are between @i[constituent] and
@i[delimiter] characters, and between @i[read-macro] characters and
non-read-macro characters. Alphabetic, numeric, and some special
characters (e.g. @tc[-] and @tc[$]) are constituent characters;
whitespace and some special characters (e.g. left and right parenthesis) are
delimiter characters. Some special characters such as @tc[(] and @tc[']
are read-macro characters; these introduce special syntactic constructs
which are idiosyncratic to the particular character introducing them.
A delimited sequence of consecutive constituent characters represents
either a @iixs[number] or a @iixs[symbol]. For example, @tc[255] represents
the integer 255, and @tc[APPEND] and @tc[append] both represent the
symbol @tc[APPEND]. Here, and throughout the manual, the term
@i[symbol] is being used in a technical manner to refer a particular
kind of named object (see section @ref[symbols section]).
Balanced parentheses with a sequence of (representations of) objects
between them represent a list of the (represented) objects. For
example, the characters @wt[(A B (C 12) D)] represent a list of four
objects, three of which are symbols, and one of which (the third one) is
a list of two objects, the symbol @tc[C] and the integer 12.
Parentheses which enclose no objects represent an empty list.
There are also external representations for strings and characters, as
well as for some kinds of objects which are syntactically illegal
as expressions (for example, vectors). Not all objects have external
representations, however.
@section[Core language]
@label[CoreLanguageSection] @Comment{ref: objects chapter}
The core language is described in terms of a hypothetical machine
(called an @iix[evaluator]) which executes @Tau[] code directly. In
practice, the existing @Tau[] implementations have (at least) two
evaluators, both of which perform evaluation as a two-stage process
consisting of compilation (syntactic and semantic analysis) followed by
interpretation.
@iix[Evaluation] is a process whereby an object called an @i[expression]
@index[expressions] (the term @i[form]@index[forms] is used synonymously
with @i[expression]) is mapped to another object, called its
@i[value]. Evaluation occurs in the context of a particular
@i[variable environment]@index[environments]; see below. The expression
is said to @iix[yield] its value.
@index[variables]
The evaluation mapping is not a purely mathematical mapping, since in
some cases the evaluation of an expression may depend not only on the
variable environment but on the @iix[state] of the running @Tau[]
system, or on the state of the world outside it; and evaluation may
cause changes in the state of system or the world, which may, in turn,
affect future evaluations. These state changes are called
@iix[side-effects].
An evaluator for the core language, written in @Tau[], can be
found in Appendix @ref[EvaluatorAppendix]. This program simply encodes
in a formal way the evaluation process (that is, the @ix[semantics])
described informally below.
The rules by which an object is evaluated are as follows:
@i[Self-evaluating literals:]@index[Literals]
All numbers, strings, and characters are syntactically valid
expressions which, when evaluated, yield themselves.
For example,
@begin[ProgramExample]
-2102 @ev[] -2102
#\M @ev[] #\M
"A string." @ev[] "A string."
@end[ProgramExample]
The notation @qu"@i[expression] @ev[] @i[value]" means that
@i[expression], when evaluated, yields @i[value]. (Note also that we are
making use of the external object syntax itself as a notational device:
@qu"the object @tc[-2102]" could be said more precisely as @qu"an object
externally represented by the characters `@tc[-2102]'." Just as a
program should never be confused with an object which represents it, an
object should never be confused with a sequence of characters
which notates it.)
@i[Symbols:]@index[Symbols]
As evaluable expressions, symbols are interpreted as variable
references. A
symbol evaluates to its value according to the current variable
environment. For example, in an environment in which the variable
@tc[DELTA] has the value @tc[15], evaluating the expression
@tc[DELTA] will yield @tc[15].
@index[variables]
Symbols have many uses other than as names for variables.
It is important not to confuse the use of a symbol as a datum
manipulated by a program with the occurrence of a symbol
as a variable reference in a program. Symbols do not have values
@i[a priori]; variables only have values by virtue of the context
in which they occur.
@i[Lists:]@index[Lists]
Non-empty lists are classified either as @iix[calls] or as @iix[special
forms]. If the first element of the list is a symbol, and the symbol is
a @iix[reserved word], then the list is a special form; otherwise it is
considered to be a @i[call]. @Tau[] reserved words
include, for example, the symbols @tc[QUOTE], @tc[IF],
and @tc[LAMBDA]. (However, see section @ref[syntax tables section].)
@i[Special forms:]@index[Special forms]
The syntax and semantics of a special form are
idiosyncratic to the reserved word which introduces it; descriptions of
the meaning of expressions introduced by the various reserved words are
therefore distributed throughout the manual.
@i[Calls:]@index[Calls]
@label[CallSemantics] @Comment{ref: object chapter, control chapter}
Calls are evaluated as follows: the elements of the list (including the
first) are evaluated, in no particular order. The first must evaluate
to a procedure; this procedure is @i[applied] @index[application] to the
rest of the values, which are called @iix[arguments].
(The verbs @i[call] and @i[invoke] mean the same as @i[apply].)
@index[calling] @index[invoking]
@comment{
Application is a process performed idiosyncratically to the procedure
being invoked, and so the description of application is decentralized,
appearing distributed throughout the manual. For example, in the
standard environment, the variable @tc[CAR] has as its value a procedure
which takes the first element of a list. The manual entry for @tc[CAR]
describes what happens when this procedure is applied to an argument,
and thus constitutes, in part, a description of application. Similarly,
the entry for @tc[LAMBDA] describes what happens when a procedure
created by a @tc[LAMBDA]-expression is invoked.
}
@section[The standard environment]
@label[StandardEnvironmentSection] @Comment{ref: locale section}
The standard environment corresponds to what is usually known as the
@qu"run-time library" in other language environments such as C or Pascal.
New variable environments may be introduced in various ways (see chapter
@ref[EnvironmentsChapter]), but a @Tau[] system is obliged to supply one
standard environment in which system variables are bound to system
procedures and constants, as defined by this manual. Program execution
typically occurs in an environment inferior to this standard environment
(see section @ref[*STANDARD-ENV*]), so that these objects are easily
accessible as values of lexically apparent variables. For example,
in this standard environment, the variable @tc[CONS] has a certain
procedure as its value.
For the most part, the values of system variables are procedures, and
therefore the only behavior of interest is what they do when called.
(See the discussion of calls, above.) In other cases, values are objects
such as numbers or symbols.
A representation of the standard environment is available as the value
of @tc[*STANDARD-ENV*] (page @pageref[*STANDARD-ENV*]).
@section[Undefined]
@label[undefined semantics section]
The term @iix[undefined] is used in two different ways in this manual.
An expression may @i[yield an undefined value], in which case it yields
some value, the particular value not being defined by this manual. In
such cases it is unwise to depend on this value having any particular
characteristics, for example, it being null, or not a number, or
whatever. The evaluation of the expression and the creation of the
undefined value are not in error; it is the use to which this value is
put that may lead to problems. Expressions yielding undefined values
are generally useful only for any side-effects they cause.
On the other hand, the evaluation of an expression may @i[have an
undefined effect], in which case an implementation will endeavor to
signal an error condition, permitting a user to take appropriate action.
For example, a call to a non-procedure, or adding two symbols together,
have undefined effects. An implementation is not @i[obliged,] however,
to signal an error, and in fact it may be in the interest of efficiency
to avoid the overhead of detecting circumstances under which undefined
effects will happen.
The two procedures @tc[UNDEFINED-VALUE] and @tc[UNDEFINED-EFFECT]
are used for expository purposes in examples throughout this manual;
they are described in section @ref[UndefinedSection].